﻿using System;
using System.IdentityModel.Tokens.Jwt;
using System.Linq;
using System.Threading.Tasks;
using VisionCloud.Domain.DtoModel.Sys;
using VisionCloud.Utility;
using VisionCloud.Utility.Cached;
using VisionCloud.Utility.Redis;
using static VisionCloud.Core.Model.Sys.SysUser;

namespace VisionCloud.Domain.Common
{
    public class OperatorBaseInfo
    {
        /// <summary>
        /// 访问模块
        /// </summary>
        public string ModuleTitle { get; set; }

        /// <summary>
        /// 访问地址
        /// </summary>
        public string VisitPath { get; set; }

        /// <summary>
        /// 浏览器
        /// </summary>
        public string Browser { get; set; }

        /// <summary>
        /// IP地址
        /// </summary>
        public string Ip { get; set; }
    }

    /// <summary>
    /// 登录用户对象
    /// </summary>
    public class OperatorInfo : OperatorBaseInfo
    {
        /// <summary>
        /// 登录人ID
        /// </summary>
        public Guid Id { get; set; }

        /// <summary>
        /// 登录Toke的Id
        /// </summary>
        public string LogId { get; set; }

        /// <summary>
        /// 登录人ID
        /// </summary>
        public Guid YunUserGuid { get; set; }

        /// <summary>
        /// 登录人名字
        /// </summary>
        public string Name { get; set; }

        /// <summary>
        /// 身份
        /// </summary>
        public string Role { get; set; }

        //未使用字段

        public string UserCode { get; set; }

        /// <summary>
        /// 项目名称
        /// </summary>
        public string Project { get; set; }

        /// <summary>
        /// 管理员
        /// </summary>
        public bool IsSuperAdministrator { get; set; }

        /// <summary>
        /// 角色代码字符串
        /// </summary>
        public String RoleCode { get; set; }

        public string OrgCode { get; set; }
        public string OrgId { get; set; }
        public string Department { get; set; }

        public int UserType { get; set; }

        /// <summary>
        /// 本次tokenId
        /// </summary>
        public string TokenId { get; set; }

        public String RoleNameList { get; set; }
        private Guid _companyGuid;

        public Guid CompanyGuid
        {
            get
            {
                if (!string.IsNullOrEmpty(this.OrgId))
                {
                    var value = Guid.TryParse(this.OrgId, out _companyGuid);
                }
                return _companyGuid;
            }
        }

        public bool IsCompanyAdmin
        {
            get
            {
                return RoleNameList.Contains("公司管理员");
            }
        }

        /// <summary>
        /// 公司名称
        /// </summary>
        public string Company { get; set; }

        /// <summary>
        /// 微信用户唯一标识OpenId
        /// </summary>
        public string WxOpenId { get; set; }

        public bool EnabledModeling { get; set; }
    }

    public class OperatorProvider
    {
        #region 临时方案,不要删除

        /// <summary>
        /// 测试临时使用
        /// </summary>
        public static bool IsUnitTest { get; set; } = false;

        /// <summary>
        /// 测试临时使用
        /// </summary>
        private static OperatorInfo LoginUser { get; set; } = null;

        #endregion 临时方案,不要删除

        private const string OperatorKey = "OperatorKey";

        public static OperatorInfo Get()
        {
            if (StartupServer.HttpContext == null)
                return default;

            var result = HttpContextCacheProvider.Get<OperatorInfo>(OperatorKey);
            //todo  这段代码应该可以不加? ,再讨论
            if (result == null && StartupServer.HttpContext.Request.Headers.ContainsKey("Authorization"))
            {
                Set(StartupServer.HttpContext.Request.Headers["Authorization"]);
                result = HttpContextCacheProvider.Get<OperatorInfo>(OperatorKey);
            }
            return result;
        }

        private static OperatorInfo Set(OperatorInfo operatorInfo)
        {
            if (StartupServer.HttpContext == null)
                return default;

            HttpContextCacheProvider.Set(OperatorKey, operatorInfo);
            return operatorInfo;
        }

        public static async Task<OperatorInfo> Set(string tokenHeader, OperatorBaseInfo baseInfo = null)
        {
            try
            {
                if (!string.IsNullOrWhiteSpace(tokenHeader))
                {
                    var jwtToken = new JwtSecurityTokenHandler().ReadJwtToken(tokenHeader.Replace("Bearer ", ""));
                    var claimList = jwtToken.Claims.ToList();
                    var operatorInfo = new OperatorInfo()
                    {
                        // 注意：拓展参数考虑新旧版本兼容
                        YunUserGuid = Guid.Parse(claimList.First(t => t.Type.Equals("YunUserGuid")).Value),
                        Id = Guid.Parse(claimList.First(t => t.Type.Equals("YunUserGuid")).Value),
                        Role = claimList.First(t => t.Type.Equals("Role"))?.Value,
                        RoleCode = claimList.First(t => t.Type.Equals("RoleCode"))?.Value,
                        Name = claimList.FirstOrDefault(t => t.Type.Equals("Name"))?.Value,
                        LogId = claimList.FirstOrDefault(t => t.Type.Equals("LogId"))?.Value,
                        OrgId = claimList.FirstOrDefault(t => t.Type.Equals("OrgId"))?.Value,
                        OrgCode = claimList.FirstOrDefault(t => t.Type.Equals("OrgCode"))?.Value,
                        UserCode = claimList.FirstOrDefault(t => t.Type.Equals("Code"))?.Value,
                        UserType = (int)System.Enum.Parse(typeof(EnumUserType), claimList.FirstOrDefault(t => t.Type.Equals("UserType")).Value),
                        TokenId = claimList.First(t => t.Type.Equals("TokenId"))?.Value,
                        RoleNameList = claimList.FirstOrDefault(t => t.Type.Equals("RoleNameList"))?.Value,
                        Company = claimList.FirstOrDefault(t => t.Type.Equals("Company"))?.Value,
                        WxOpenId = claimList.FirstOrDefault(t => t.Type.Equals("WxOpenId"))?.Value,
                    };

                    bool IsLogOutValue = await RedisHelper.Instance.GetAsync<bool>(operatorInfo.YunUserGuid + operatorInfo.TokenId);
                    if (IsLogOutValue)
                    {
                        return null;
                    }
                    SysUserDto userInfo = await RedisHelper.Instance.GetAsync<SysUserDto>(operatorInfo.LogId);
                    if (userInfo == null)
                    {
                        return null;
                    }

                    return baseInfo != null
                        ? Set(operatorInfo, baseInfo)
                        : Set(operatorInfo);
                }
            }
            catch (Exception ex)
            {
                Logger.Error($"OperatorProvider.Set发生错误。参数tokenHeader为【{tokenHeader}】，错误信息：【{ex.Message}】，StackTrace：{ex.StackTrace}");
            }
            return null;
        }

        public static OperatorInfo Set(OperatorInfo operatorInfo, OperatorBaseInfo baseInfo)
        {
            operatorInfo.Browser = baseInfo.Browser;
            operatorInfo.Ip = baseInfo.Ip;
            operatorInfo.ModuleTitle = baseInfo.ModuleTitle;
            operatorInfo.VisitPath = baseInfo.VisitPath;
            Set(operatorInfo);
            return operatorInfo;
        }
    }
}